#ifndef _XX_YY_BMOCK_EXPECTATION
#define _XX_YY_BMOCK_EXPECTATION
#include <string>
#include <vector>
#include "bmock_exp_checker.hpp"
#include "bmock_arg_list.hpp"
#include "bmock_control_tools.hpp"
#include "bmock_result.hpp"

namespace bmock {
	struct infinite_calls {};

	struct expectation {
		typedef exp_checker::slot_type slot_type;

		expectation(const control_tools_ptr &);
		void        expect_call(const func_spec &fn,const location &);
		void        expect_arguments(const arg_list &args);	
		void		expect_call_times_range(int min_, int max_);
		void		set_infinite_calls() { calls_.infinite_ = true;}
		void		add_actual_call();
		bool		is_last_call() const;
		bool		done_minimum_calls() const;
		void        set_result(const result_ptr &r) { p_result_ = r; }
		result_ptr  check(const func_spec &fn,const arg_list &args) const;
		result_ptr  check_stub(const func_spec &fn,const arg_list &args) const;
		void		check_func(const func_spec &fn) const;
		result_ptr get_result() const { return p_result_; }
		bool check_non_strict(const func_spec& fn, const arg_list& args) const;
		void check_args_no_msg(const arg_list &args) const;
		const func_spec& get_func_spec() const { return func_; }
		void        not_received();
		void        connect(const slot_type &slot) {
			checker_.connect(slot);
		}
	private:				
		exp_checker               checker_;
		func_spec                 func_;		
		std::vector<arg_val_str>  arg_vals_;	
		result_ptr                p_result_;	
		
		struct Calls {
			Calls():min_(1),max_(1),actaul_(0),infinite_(false) {}
			int min_, max_, actaul_;
			bool infinite_;
		};
		Calls calls_;
	};
};

#endif